﻿// -----------------------------------------------------------------------
// <copyright file="ConfigurationFileManager.cs" company="Microsoft">
//  ???
// </copyright>
// -----------------------------------------------------------------------

namespace Eeeek.Configuration
{
    using System;
    using System.Reflection;
    using System.Xml;

    /// <summary>
    /// Manages the config file 
    /// </summary>
    public class ConfigurationFileManager : System.Configuration.AppSettingsReader
    {
        /// <summary>
        /// Thee config file.
        /// </summary>
        private readonly string configurationFile;

        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigurationFileManager"/> class.
        /// </summary>
        /// <param name="configurationFile">The configuration file.</param>
        public ConfigurationFileManager(string configurationFile)
        {
            this.configurationFile = configurationFile;
        }

        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <typeparam name="T">The type to retrieve</typeparam>
        /// <param name="key">The key.</param>
        /// <returns>The value associated with the key</returns>
        public T GetValue<T>(string key)
        {
            object rawObject = this.GetValue(key, typeof(T));
            return (T)rawObject;
        }

        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The val.</param>
        public void SetValue(string key, string value)
        {
            var document = new XmlDocument();
            this.LoadDocument(document);

            // retrieve appSettings node
            XmlNode configurationNode = document.SelectSingleNode("//appSettings");

            if (configurationNode == null)
            {
                throw new InvalidOperationException("appSettings section not found in config file.");
            }

            // select the 'add' element that contains the key
            var element = (XmlElement)configurationNode.SelectSingleNode(string.Format("//add[@key='{0}']", key));

            if (element != null)
            {
                // add value for key
                element.SetAttribute("value", value);
            }
            else
            {
                // key was not found so create the 'add' element 
                // and set it's key/value attributes 
                element = document.CreateElement("add");
                element.SetAttribute("key", key);
                element.SetAttribute("value", value);
                configurationNode.AppendChild(element);
            }

            document.Save(GetConfigFilePath());
        }

        /// <summary>
        /// Gets the config file path.
        /// </summary>
        /// <returns>The path as a string</returns>
        private static string GetConfigFilePath()
        {
            return Assembly.GetExecutingAssembly().Location + ".config";
        }

        /// <summary>
        /// Loads the document.
        /// </summary>
        /// <param name="document">The doc.</param>
        private void LoadDocument(XmlDocument document)
        {
            document.Load(this.configurationFile);
        }
    }
}
